<template>
  <li :class="classes" @mouseenter="handleMouseenter" @mouseleave="handleMouseleave">
    <div ref="reference" :class="[prefixCls + '-submenu-title']" :style="titleStyle" @click.stop="handleClick">
      <slot name="title"></slot>
      <Icon :type="arrowType" :custom="customArrowType" :size="arrowSize" :class="[prefixCls + '-submenu-title-icon']" />
    </div>
    <collapse-transition v-if="mode === 'vertical'">
      <ul v-show="opened" :class="[prefixCls]">
        <slot></slot>
      </ul>
    </collapse-transition>
    <transition v-else name="slide-up">
      <Drop v-show="opened" ref="drop" placement="bottom" :style="dropStyle">
        <ul :class="[prefixCls + '-drop-list']">
          <slot></slot>
        </ul>
      </Drop>
    </transition>
  </li>
</template>
<script>
import Drop from '../select/dropdown.vue';
import Icon from '../icon/icon.vue';
import CollapseTransition from '../base/collapse-transition';
import { getStyle, findComponentUpward, findComponentsDownward } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixin from './mixin';

const prefixCls = 'ivu-menu';

export default {
  name: 'Submenu',
  components: { Icon, Drop, CollapseTransition },
  mixins: [Emitter, mixin],
  props: {
    name: {
      type: [String, Number],
      required: true
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      prefixCls: prefixCls,
      active: false,
      opened: false,
      dropWidth: parseFloat(getStyle(this.$el, 'width'))
    };
  },
  mounted() {
    this.$on('on-menu-item-select', name => {
      if (this.mode === 'horizontal') this.opened = false;
      this.dispatch('Menu', 'on-menu-item-select', name);
      return true;
    });
    this.$on('on-update-active-name', status => {
      if (findComponentUpward(this, 'Submenu')) this.dispatch('Submenu', 'on-update-active-name', status);
      if (findComponentsDownward(this, 'Submenu')) {
        findComponentsDownward(this, 'Submenu').forEach(item => {
          item.active = false;
        }); 
      }
      this.active = status;
    });
  },
  methods: {
    handleMouseenter() {
      if (this.disabled) return;
      if (this.mode === 'vertical') return;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(() => {
        this.menu.updateOpenKeys(this.name);
        this.opened = true;
      }, 250);
    },
    handleMouseleave() {
      if (this.disabled) return;
      if (this.mode === 'vertical') return;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(() => {
        this.menu.updateOpenKeys(this.name);
        this.opened = false;
      }, 150);
    },
    handleClick() {
      if (this.disabled) return;
      if (this.mode === 'horizontal') return;
      const opened = this.opened;
      if (this.accordion) {
        this.$parent.$children.forEach(item => {
          if (item.$options.name === 'Submenu') item.opened = false;
        });
      }
      this.opened = !opened;
      this.menu.updateOpenKeys(this.name);
    }
  },
  computed: {
    classes() {
      return [
        `${prefixCls}-submenu`,
        {
          [`${prefixCls}-item-active`]: this.active && !this.hasParentSubmenu,
          [`${prefixCls}-opened`]: this.opened,
          [`${prefixCls}-submenu-disabled`]: this.disabled,
          [`${prefixCls}-submenu-has-parent-submenu`]: this.hasParentSubmenu,
          [`${prefixCls}-child-item-active`]: this.active
        }
      ];
    },
    accordion() {
      return this.menu.accordion;
    },
    dropStyle() {
      let style = {};

      if (this.dropWidth) style.minWidth = `${this.dropWidth}px`;
      return style;
    },
    titleStyle() {
      return this.hasParentSubmenu && this.mode !== 'horizontal'
        ? {
          paddingLeft: 43 + (this.parentSubmenuNum - 1) * 24 + 'px'
        }
        : {};
    },
    // 3.4.0, global setting customArrow 有值时，arrow 赋值空
    arrowType() {
      let type = 'ios-arrow-down';

      if (this.$IVIEW) {
        if (this.$IVIEW.menu.customArrow) {
          type = '';
        } else if (this.$IVIEW.menu.arrow) {
          type = this.$IVIEW.menu.arrow;
        }
      }
      return type;
    },
    // 3.4.0, global setting
    customArrowType() {
      let type = '';

      if (this.$IVIEW) {
        if (this.$IVIEW.menu.customArrow) {
          type = this.$IVIEW.menu.customArrow;
        }
      }
      return type;
    },
    // 3.4.0, global setting
    arrowSize() {
      let size = '';

      if (this.$IVIEW) {
        if (this.$IVIEW.menu.arrowSize) {
          size = this.$IVIEW.menu.arrowSize;
        }
      }
      return size;
    }
  },
  watch: {
    mode(val) {
      if (val === 'horizontal') {
        this.$refs.drop.update();
      }
    },
    opened(val) {
      if (this.mode === 'vertical') return;
      if (val) {
        // set drop a width to fixed when menu has fixed position
        this.dropWidth = parseFloat(getStyle(this.$el, 'width'));
        this.$refs.drop.update();
      } else {
        this.$refs.drop.destroy();
      }
    }
  }
};
</script>
